package denoise;

import java.awt.image.BufferedImage;

public class LoopyBeliefAgent implements DenoiseAgent
{
    public BufferedImage denoise(BufferedImage in, BufferedImage[] training)
    {
        int width = in.getWidth(), height = in.getHeight();
        double beta = 1.0;
        double theta = 2.1;
        BufferedImage out = new BufferedImage(width, height,
                                              BufferedImage.TYPE_INT_RGB);

        for (int i = 0; i < width; i++)
        {
            for (int j = 0; j < height; j++)
            {
                out.setRGB(i, j, in.getRGB(i, j));
            }
        }

        int changedpixels = 0;

        while (changedpixels == 0) {
            changedpixels = 0;
            int x = 0, y = 0, pta = 0, ptb = 0, ptl = 0, ptr = 0;
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    x = findmap(out.getRGB(i, j));
                    y = findmap(in.getRGB(i, j));
                    if (i - 1 >= 0)
                    {
                        ptl = findmap(out.getRGB(i - 1, j));
                    }
                    if (i + 1 < width)
                    {
                        ptr = findmap(out.getRGB(i + 1, j));
                    }
                    if (j - 1 >= 0)
                    {
                        pta = findmap(out.getRGB(i, j - 1));
                    }
                    if (j + 1 < height)
                    {
                        ptb = findmap(out.getRGB(i, j + 1));
                    }

                    int ptsum = pta + ptb + ptl + ptr;
                    int neighbour = ptsum * x;
                    int xy = x * y;

                    double calcpotential = -(theta * xy) - (beta * neighbour);

                    int negneighbour = ptsum * -1;
                    int negy = y * -1;
                    double negpotential = -theta * negy - beta * negneighbour;

                    int posneighbour = ptsum * 1;
                    int posy = y * 1;
                    double pospotential = -theta * posy - beta * posneighbour;
                    
                    if (pospotential < negpotential)
                    {
                        if (pospotential != calcpotential)
                        {
                            out.setRGB(i, j, 0xFFFFFF);
                            changedpixels++;
                        }

                    }
                    if (pospotential > negpotential)
                    {
                        if (negpotential != calcpotential)
                        {
                            out.setRGB(i, j, 0x000000);
                            changedpixels++;
                        }
                    }
                }
            }

        }

        return out;
    }

    int findmap(int rgb)
    {
        if ((rgb & 0xff) >= 0x80)
            return 1;
        else
            return -1;
    }
}
